//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package org_member_api_serv

import (
	"context"

	"atomgit.com/openlinksaas/api-server/dao"
	"atomgit.com/openlinksaas/api-server/dao/org_dao"
	"atomgit.com/openlinksaas/api-server/dao/project_dao"
	"atomgit.com/openlinksaas/api-server/dao/user_dao"
	"atomgit.com/openlinksaas/api-server/utils"
	"atomgit.com/openlinksaas/proto-gen-go.git/org_member_api"
)

func (apiImpl *OrgMemberApiImpl) ListForProject(ctx context.Context, req *org_member_api.ListForProjectRequest) (*org_member_api.ListForProjectResponse, error) {
	emptyList := []*org_member_api.ProjectMemberInfo{}

	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_member_api.ListForProjectResponse{
			Code:       org_member_api.ListForProjectResponse_CODE_WRONG_SESSION,
			ErrMsg:     "会话不存在",
			MemberList: emptyList,
		}, nil
	}
	//检测权限
	projectItem, _, userRoleItem, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &org_member_api.ListForProjectResponse{
			Code:       org_member_api.ListForProjectResponse_CODE_NO_PROJECT,
			ErrMsg:     "项目不存在",
			MemberList: emptyList,
		}, nil
	} else if err == utils.ErrNoRole {
		return &org_member_api.ListForProjectResponse{
			Code:       org_member_api.ListForProjectResponse_CODE_NO_PERMISSION,
			ErrMsg:     "没有权限",
			MemberList: emptyList,
		}, nil
	} else if err != nil {
		return nil, err
	}

	if !(sessionItem.UserId == projectItem.OwnerUserId || userRoleItem.BasicInfo.Admin) {
		return &org_member_api.ListForProjectResponse{
			Code:       org_member_api.ListForProjectResponse_CODE_NO_PERMISSION,
			ErrMsg:     "没有权限",
			MemberList: emptyList,
		}, nil
	}

	//检查组织是否存在
	exist, err := org_dao.OrgInfoDao.Exist(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &org_member_api.ListForProjectResponse{
			Code:       org_member_api.ListForProjectResponse_CODE_NO_ORG,
			ErrMsg:     "组织不存在",
			MemberList: emptyList,
		}, nil
	}
	exist, err = org_dao.MemberDao.Exist(ctx, req.OrgId, sessionItem.UserId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &org_member_api.ListForProjectResponse{
			Code:       org_member_api.ListForProjectResponse_CODE_NO_PERMISSION,
			ErrMsg:     "没有权限",
			MemberList: emptyList,
		}, nil
	}

	//获取项目成员
	prjMemberItemList, err := project_dao.MemberInfoDao.ListMember(ctx, req.ProjectId)
	if err != nil {
		return nil, err
	}
	prjMemberMap := map[string]bool{}
	for _, prjMemberItem := range prjMemberItemList {
		prjMemberMap[prjMemberItem.MemberUserId] = true
	}
	//获取待加入成员
	joinAckItemList, err := project_dao.AckJoinDao.ListByProject(ctx, req.ProjectId)
	if err != nil {
		return nil, err
	}
	ackMemberMap := map[string]bool{}
	for _, joinAckItem := range joinAckItemList {
		ackMemberMap[joinAckItem.MemberUserId] = true
	}
	//列出组织成员
	orgMemberItemList, err := org_dao.MemberDao.ListByOrg(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}

	//补充用户信息
	userIdList := []string{}
	for _, orgMemberItem := range orgMemberItemList {
		userIdList = append(userIdList, orgMemberItem.MemberUserId)
	}
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, userIdList)
	if err != nil {
		return nil, err
	}
	userItemMap := map[string]*user_dao.UserInfoDbItem{}
	for _, userItem := range userItemList {
		userItemMap[userItem.UserId] = userItem
	}

	//生成结果
	memberList := []*org_member_api.ProjectMemberInfo{}
	for _, orgMemberItem := range orgMemberItemList {
		member := &org_member_api.ProjectMemberInfo{
			MemberUserId:       orgMemberItem.MemberUserId,
			ProjectMemberState: org_member_api.PROJECT_MEMBER_STATE_MEMBER_UNJOIN,
		}
		if ackMemberMap[orgMemberItem.MemberUserId] {
			member.ProjectMemberState = org_member_api.PROJECT_MEMBER_STATE_MEMBER_TO_ACK_JOIN
		}
		if prjMemberMap[orgMemberItem.MemberUserId] {
			member.ProjectMemberState = org_member_api.PROJECT_MEMBER_STATE_MEMBER_IN_PROJECT
		}
		userItem, ok := userItemMap[orgMemberItem.MemberUserId]
		if ok {
			member.DisplayName = userItem.BasicInfo.DisplayName
			member.LogoUri = userItem.BasicInfo.LogoUri
		}
		memberList = append(memberList, member)
	}

	return &org_member_api.ListForProjectResponse{
		Code:       org_member_api.ListForProjectResponse_CODE_OK,
		MemberList: memberList,
	}, nil
}
